package com.seago.iceberg.config;

import com.seago.iceberg.repository.SimpleIcebergRepository;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Title:
 * <p>
 * description:
 *
 * @Company: 中国船舶集团海舟系统技术有限公司-武汉
 * @author: yangs
 * @since: 2023-05-09 09:35
 * @version: 1.0
 **/
public class IcebergRepositoryInvocationHandler<S, ID> implements InvocationHandler {

	private final Class<S> entityType;
	private final Class<ID> idType;

	private final Map<Class<?>, SimpleIcebergRepository<?, ?>> repositoryMap;


	public IcebergRepositoryInvocationHandler(Class<S> entityType, Class<ID> idType) {
		this.entityType = entityType;
		this.idType = idType;
		this.repositoryMap = new ConcurrentHashMap<>();
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		SimpleIcebergRepository<S, ID> repository = getRepository(entityType);
		Method jpaMethod = repository.getClass().getMethod(method.getName(), method.getParameterTypes());
		return jpaMethod.invoke(repository, args);
	}

	@SuppressWarnings("unchecked")
	private SimpleIcebergRepository<S, ID> getRepository(Class<?> key) {
		return (SimpleIcebergRepository<S, ID>) repositoryMap.computeIfAbsent(key, k -> new SimpleIcebergRepository(entityType, idType));
	}
}
